package com.farm.template.service.impl;

import com.farm.template.domain.Template;
import com.farm.template.domain.TemplateDir;
import com.farm.template.domain.TemplateFile;
import com.farm.template.domain.ex.SysDir;
import com.farm.core.time.TimeTool;
import com.farm.parameter.FarmParameterService;
import com.farm.project.domain.ProjectActive;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.ss.formula.functions.T;

import com.farm.template.dao.TemplateDaoInter;
import com.farm.template.dao.TemplatedirDaoInter;
import com.farm.template.dao.TemplatefileDaoInter;
import com.farm.template.service.TemplateServiceInter;
import com.farm.template.utils.FarmStringUtils;
import com.farm.template.utils.FreeMarkerUtils;
import com.farm.web.WebUtils;
import com.farm.core.sql.query.DBRule;
import com.farm.core.sql.query.DBRuleList;
import com.farm.core.sql.query.DataQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;
import com.farm.core.auth.domain.LoginUser;

/* *
 *功能：模板定义服务层实现类
 *详细：
 *
 *版本：v0.1
 *作者：FarmCode代码工程
 *日期：20150707114057
 *说明：
 */
@Service
public class TemplateServiceImpl implements TemplateServiceInter {
	@Resource
	private TemplateDaoInter templateDaoImpl;
	@Resource
	private TemplatedirDaoInter templatedirDaoImpl;
	@Resource
	private TemplatefileDaoInter templatefileDaoImpl;
	private static final Logger log = Logger.getLogger(TemplateServiceImpl.class);

	@Override
	@Transactional
	public Template insertTemplateEntity(Template entity, LoginUser user) {
		entity.setCuser(user.getId());
		entity.setCtime(TimeTool.getTimeDate14());
		entity.setEuser(user.getId());
		entity.setEtime(TimeTool.getTimeDate14());
		entity.setPstate("1");
		if (!isExistCode(entity.getCode(), null)) {
			return templateDaoImpl.insertEntity(entity);
		} else {
			throw new RuntimeException("该代码已经存在，请不要重复创建!");
		}

	}

	private boolean isExistCode(String code, String thisId) {
		DBRuleList dbs = DBRuleList.getInstance();
		dbs.add(new DBRule("CODE", code, "="));
		if (thisId != null) {
			dbs.add(new DBRule("ID", thisId, "!="));
		}
		List<Template> list = templateDaoImpl.selectEntitys(dbs.toList());
		return list.size() > 0;
	}

	@Override
	@Transactional
	public Template editTemplateEntity(Template entity, LoginUser user) {
		Template entity2 = templateDaoImpl.getEntity(entity.getId());
		entity2.setEuser(user.getId());
		entity2.setEtime(TimeTool.getTimeDate14());
		entity2.setName(entity.getName());
		entity2.setCode(entity.getCode());
		entity2.setPcontent(entity.getPcontent());
		entity2.setPstate(entity.getPstate());
		if (!isExistCode(entity.getCode(), entity2.getId())) {
			templateDaoImpl.editEntity(entity2);
		} else {
			throw new RuntimeException("该代码已经存在，请不要重复创建!");
		}
		return entity2;
	}

	@Override
	@Transactional
	public void deleteTemplateEntity(String id, LoginUser user) {
		Template tmp = templateDaoImpl.getEntity(id);
		if (tmp.getPstate().equals("9")) {
			throw new RuntimeException("模板存档禁止操作!");
		}
		List<DBRule> rules = DBRuleList.getInstance().add(new DBRule("TEMPLATEID", id, "=")).toList();
		templatedirDaoImpl.deleteEntitys(rules);
		templatefileDaoImpl.deleteEntitys(rules);
		templateDaoImpl.deleteEntity(tmp);

	}

	@Override
	@Transactional
	public Template getTemplateEntity(String id) {
		// TODO 自动生成代码,修改后请去除本注释
		if (id == null) {
			return null;
		}
		return templateDaoImpl.getEntity(id);
	}

	@Override
	@Transactional
	public DataQuery createTemplateSimpleQuery(DataQuery query) {
		// TODO 自动生成代码,修改后请去除本注释
		DataQuery dbQuery = DataQuery.init(query, "CBTG_TEMPLATE a left join CBTG_APP_CATALOG b on b.id=a.catalogid",
				"A.ID as ID,A.CATALOGID as CATALOGID,B.NAME as CATALOGNAME,a.NAME as NAME,a.CODE as CODE,a.PCONTENT as PCONTENT,a.PSTATE as PSTATE,a.EUSER as EUSER,a.CTIME as CTIME,a.ETIME as ETIME,a.CUSER as CUSER");
		return dbQuery;
	}

	@Override
	@Transactional
	public void updateCatalog(String tids, String catalogId, LoginUser currentUser) {
		for (String templateId : WebUtils.parseIds(tids)) {
			Template temp = templateDaoImpl.getEntity(templateId);
			temp.setCatalogid(catalogId);
			templateDaoImpl.editEntity(temp);
		}
	}

	@Override
	@Transactional
	public List<TemplateDir> getTemplateDirs(String templateId) {
		return templatedirDaoImpl
				.selectEntitys(DBRuleList.getInstance().add(new DBRule("TEMPLATEID", templateId, "=")).toList());
	}

	@Override
	@Transactional
	public List<TemplateFile> getTemplateFiles(String templateId) {
		return templatefileDaoImpl
				.selectEntitys(DBRuleList.getInstance().add(new DBRule("TEMPLATEID", templateId, "=")).toList());
	}

	@Override
	@Transactional
	public List<SysDir> getTemplateDir(TemplateDir dir, Map<String, Object> attrs) {
		List<SysDir> dirs = new ArrayList<SysDir>();
		for (String dirId : FarmStringUtils.splitByCharacterCount(dir.getTreecode(), 32)) {
			TemplateDir tdir = templatedirDaoImpl.getEntity(dirId);
			dirs.add(new SysDir(tdir.getId(), FreeMarkerUtils.getTemplateString(tdir.getCode(), attrs, dir.getName()),
					tdir.getCode()));
		}
		return dirs;
	}

	@Override
	@Transactional
	public String creatSysDir(List<SysDir> sysdirs, ProjectActive active, Template template) {
		String activepath = FreeMarkerUtils.getActiveTemplatePath(active.getId(), template.getCode());
		String dirpath = File.separator;
		for (SysDir dri : sysdirs) {
			dirpath = dirpath + File.separator + dri.getFilename();
		}
		File file = new File(activepath + dirpath);
		if (file.mkdirs()) {
			System.out.println("Directory created: " + file.getAbsolutePath());
		} else {
			System.out.println("Directory already exists or could not be created.");
		}
		return file.getPath();
	}

	@Override
	@Transactional
	public String creatCopy(String templateId, LoginUser currentUser) {
		try {
			List<DBRule> rules = DBRuleList.getInstance().add(new DBRule("TEMPLATEID", templateId, "=")).toList();
			Map<String, String> copyIdDic = new HashMap<String, String>();
			copyIdDic.put("NONE", "NONE");
			// 读取和拷贝 CBTG_TEMPLATE
			{
				Template template = templateDaoImpl.getEntity(templateId);
				Template newTemplate = new Template();
				BeanUtils.copyProperties(newTemplate, template);
				newTemplate.setId(null);
				newTemplate.setCode(template.getCode() + TimeTool.getFormatTimeDate("_mmss"));
				newTemplate.setName(newTemplate.getName() + "_副本");
				newTemplate = templateDaoImpl.insertEntity(newTemplate);
				copyIdDic.put(template.getId(), newTemplate.getId());
			}
			// 读取和拷贝 CBTG_TEMPLATE_DIR
			{
				List<TemplateDir> newDirs = new ArrayList<TemplateDir>();
				List<TemplateDir> dirs = templatedirDaoImpl.selectEntitys(rules);
				dirs.sort(new Comparator<TemplateDir>() {
					@Override
					public int compare(TemplateDir o1, TemplateDir o2) {
						return o1.getTreecode().length() - o2.getTreecode().length();
					}
				});
				for (TemplateDir dir : dirs) {
					TemplateDir newObj = new TemplateDir();
					BeanUtils.copyProperties(newObj, dir);
					newObj.setId(null);
					newObj.setParentid(copyIdDic.get(dir.getParentid()));
					newObj.setTemplateid(copyIdDic.get(dir.getTemplateid()));
					newObj = templatedirDaoImpl.insertEntity(newObj);
					copyIdDic.put(dir.getId(), newObj.getId());
					newDirs.add(newObj);
				}
				for (TemplateDir dir : newDirs) {
					String treecode = dir.getTreecode();
					for (Entry<String, String> node : copyIdDic.entrySet()) {
						treecode = treecode.replace(node.getKey(), node.getValue());
					}
					dir.setTreecode(treecode);
					templatedirDaoImpl.editEntity(dir);
				}
			}
			// 读取和拷贝 CBTG_TEMPLATE_FILE
			{
				List<TemplateFile> files = templatefileDaoImpl.selectEntitys(rules);
				for (TemplateFile file : files) {
					TemplateFile newObj = new TemplateFile();
					BeanUtils.copyProperties(newObj, file);
					newObj.setId(null);
					newObj.setDirid(copyIdDic.get(file.getDirid()));
					newObj.setTemplateid(copyIdDic.get(file.getTemplateid()));
					newObj = templatefileDaoImpl.insertEntity(newObj);
					copyIdDic.put(file.getId(), newObj.getId());
				}
			}
			return copyIdDic.get(templateId);
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
}
